package com.ssy.lingxi.pay.controller.pc.eAccount;

import cn.hutool.core.bean.BeanUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.controller.BaseController;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.component.redis.utils.SerialNumberUtils;
import com.ssy.lingxi.pay.api.common.EAccountStatusEnum;
import com.ssy.lingxi.pay.api.common.allInPay.AllInPayEnterpriseStateEnum;
import com.ssy.lingxi.pay.api.common.allInPay.AllInPayPersonalStateEnum;
import com.ssy.lingxi.pay.api.dto.request.eAccount.EAccountQueryRequest;
import com.ssy.lingxi.pay.api.dto.request.eAccount.FreezeEAccountRequest;
import com.ssy.lingxi.pay.api.dto.request.eAccount.UnFreezeEAccountRequest;
import com.ssy.lingxi.pay.api.dto.response.eAccount.PlatFormEAccountDetailResponse;
import com.ssy.lingxi.pay.api.dto.response.eAccount.PlatFormEAccountResponse;
import com.ssy.lingxi.pay.api.model.vo.request.allInPay.BalanceVO;
import com.ssy.lingxi.pay.api.model.vo.request.allInPay.FreezeMoneyReqVO;
import com.ssy.lingxi.pay.api.model.vo.request.allInPay.dto.QueryInExpDetailDTO;
import com.ssy.lingxi.pay.api.model.vo.response.allInPay.FreezeMoneyRespVO;
import com.ssy.lingxi.pay.api.model.vo.response.allInPay.InExpDetail;
import com.ssy.lingxi.pay.api.model.vo.response.allInPay.QueryInExpDetailRespVO;
import com.ssy.lingxi.pay.entity.allInPay.AllInPay;
import com.ssy.lingxi.pay.entity.eAccount.EAccountStatusRecord;
import com.ssy.lingxi.pay.service.allInPay.IAllInPayService;
import com.ssy.lingxi.pay.service.eAccount.IEAccountService;
import com.ssy.lingxi.pay.service.eAccount.IEAccountStatusService;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @menu: 平台后台e账户管理-通联
 * @author jw.chen
 * @version 2.0.0
 * @date 2021/12/2
 */
@RestController
@RequestMapping("/pay/platForm/eAccount/allInPay")
public class PlatFormEAccountController extends BaseController {

    @Resource
    private IEAccountService eAccountService;

    @Resource
    private IAllInPayService payService;

    @Resource
    private IEAccountStatusService eAccountStatusService;

    @Resource
    private IRedisStringUtils redisStringUtils;

    /**
     * 查询e账户列表
     * @param pageVO 分页实体
     * @param eAccountQueryRequest 查询参数
     */
    @RequestMapping(value = "/getPlatFormEAccountList", method = RequestMethod.GET)
    public Wrapper<PageData<PlatFormEAccountResponse>> getPlatFormEAccountList(PageVO pageVO, EAccountQueryRequest eAccountQueryRequest) {
        Page<AllInPay> result = eAccountService.getPlatFormEAccountList(pageVO, eAccountQueryRequest);
        List<PlatFormEAccountResponse> resultList = result.getContent().stream().map(allInPay -> {
            PlatFormEAccountResponse platFormEAccountResponse = BeanUtil.copyProperties(allInPay, PlatFormEAccountResponse.class);
            //账户状态
            Integer allInMemberType = allInPay.getAllInMemberType();
            Integer accountStatus = allInPay.getAccountStatus();
            platFormEAccountResponse.setAllInMemberType(allInMemberType);
            if(allInMemberType != null && allInMemberType.equals(3)){
                platFormEAccountResponse.setAccountStatusName(AllInPayPersonalStateEnum.getName(accountStatus));
            }
            if(allInMemberType != null && allInMemberType.equals(2)){
                platFormEAccountResponse.setAccountStatusName(AllInPayEnterpriseStateEnum.getName(accountStatus));
            }
            return platFormEAccountResponse;
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * e账户详情
     * @param id e账户id
     */
    @RequestMapping(value = "/getPlatFormEAccount", method = RequestMethod.GET)
    public Wrapper<PlatFormEAccountDetailResponse> getPlatFormEAccount(@RequestParam Long id) {
        AllInPay allInPay = eAccountService.getAccountDetail(id);
        if(allInPay != null){
            PlatFormEAccountDetailResponse eAccountResponse = BeanUtil.copyProperties(allInPay, PlatFormEAccountDetailResponse.class);

            //账户状态
            Integer allInMemberType = allInPay.getAllInMemberType();
            Integer accountStatus = allInPay.getAccountStatus();
            eAccountResponse.setAllInMemberType(allInMemberType);
            if(allInMemberType != null && allInMemberType.equals(3)){
                eAccountResponse.setAccountStatusName(AllInPayPersonalStateEnum.getName(accountStatus));
            }
            if(allInMemberType != null && allInMemberType.equals(2)){
                eAccountResponse.setAccountStatusName(AllInPayEnterpriseStateEnum.getName(accountStatus));
            }

            //查询账户余额
            BalanceVO balanceVO = payService.queryBalance(allInPay.getMemberId(), allInPay.getMemberRoleId());
            //账户信息
            eAccountResponse.setAccountBalance(balanceVO.getAllAmount());
            eAccountResponse.setLockBalance(balanceVO.getFreeZenAmount());
            eAccountResponse.setUsableBalance(balanceVO.getAvailableAmount());

            return Wrapper.success(eAccountResponse);
        }else{
            throw new BusinessException(ResponseCode.PAY_E_ACCOUNT_NOT_EXIST);
        }
    }

    /**
     * 交易记录
     * @param id e账号id
     * @param startTime 开始时间,格式:yyyy-MM-dd HH:mm:ss
     * @param endTime 结束时间,格式:yyyy-MM-dd HH:mm:ss
     */
    @RequestMapping(value = "/getEAccountTradeRecord", method = RequestMethod.GET)
    public Wrapper<PageData<InExpDetail>> getEAccountTradeRecord(PageVO pageVO, @RequestParam("id") Long id, @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        AllInPay allInPay = eAccountService.getAccountDetail(id);
        if(allInPay != null) {
            QueryInExpDetailDTO dto = new QueryInExpDetailDTO();
            dto.setDateStart(startTime);
            dto.setDateEnd(endTime);
            dto.setQueryNum((long) pageVO.getPageSize());
            dto.setStartPosition((long) pageVO.getCurrentOffset() + 1);
            QueryInExpDetailRespVO queryInExpDetailRespVO = payService.queryInExpDetail(allInPay.getMemberId(), allInPay.getMemberRoleId(), dto);
            if(queryInExpDetailRespVO != null){
                return Wrapper.success(new PageData<>(queryInExpDetailRespVO.getTotalNum(), queryInExpDetailRespVO.getInExpDetails()));
            }else{
                return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
            }
        }else{
            throw new BusinessException(ResponseCode.PAY_E_ACCOUNT_NOT_EXIST);
        }
    }

    /**
     * 状态记录
     * @param id e账户id
     */
    @RequestMapping(value = "/getEAccountStatusRecord", method = RequestMethod.GET)
    public Wrapper<List<EAccountStatusRecord>> getEAccountStatusRecord(@RequestParam("id") Long id) {
        return Wrapper.success(eAccountStatusService.getEAccountStatusRecord(id));
    }

    /**
     * 冻结e账户金额
     * @param eAccountStatusRequest 参数
     */
    @RequestMapping(value = "/freezeEAccount", method = RequestMethod.POST)
    public Wrapper<Boolean> freezeEAccount(@RequestBody @Valid FreezeEAccountRequest eAccountStatusRequest) {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long id = eAccountStatusRequest.getId();
        AllInPay allInPay = eAccountService.getAccountDetail(id);
        if(allInPay != null){
            String remark = eAccountStatusRequest.getRemark();
            BigDecimal amount = eAccountStatusRequest.getAmount();

            //交易订单号
            String tradeCode = SerialNumberUtils.getNumber(redisStringUtils, Constants.ACCOUNT_TRACE_CODE, Constants.REDIS_ORDER_INDEX, Constants.ACCOUNT_TRACE_CODE_DATE, Constants.ACCOUNT_TRACE_CODE_NUM_LEN);

            FreezeMoneyReqVO freezeMoneyReqVO = new FreezeMoneyReqVO();
            freezeMoneyReqVO.setAmount(amount);
            freezeMoneyReqVO.setType(EAccountStatusEnum.freeze.getCode());
            freezeMoneyReqVO.setBizFreeZenNo(tradeCode);
            FreezeMoneyRespVO freezeMoneyRespVO = payService.freezeMoney(allInPay.getMemberId(), allInPay.getMemberRoleId(), freezeMoneyReqVO);
            if(freezeMoneyRespVO != null){
                EAccountStatusRecord eAccountStatusRecord = new EAccountStatusRecord();
                eAccountStatusRecord.setAllInPayId(allInPay.getId());
                eAccountStatusRecord.setStatus(EAccountStatusEnum.freeze.getCode());
                eAccountStatusRecord.setOperation(EAccountStatusEnum.freeze.getCode());
                eAccountStatusRecord.setAmount(amount);
                eAccountStatusRecord.setTraceNo(tradeCode);
                eAccountStatusRecord.setAllInPayAmount(freezeMoneyRespVO.getAmount());
                eAccountStatusRecord.setAllInPayTraceNo(freezeMoneyRespVO.getBizFreeZenNo());
                eAccountStatusRecord.setRemark(remark);
                eAccountStatusRecord.setCreateTime(System.currentTimeMillis());
                eAccountStatusRecord.setMemberId(sysUser.getMemberId());
                eAccountStatusRecord.setMemberName(sysUser.getCompany());
                eAccountStatusRecord.setMemberRoleId(sysUser.getMemberRoleId());
                eAccountStatusRecord.setMemberRoleName(sysUser.getMemberRoleName());
                eAccountStatusService.saveEAccountStatusRecord(eAccountStatusRecord);
                return Wrapper.success(true);
            }else{
                return Wrapper.success(false);
            }
        }else{
            throw new BusinessException(ResponseCode.PAY_E_ACCOUNT_NOT_EXIST);
        }
    }

    /**
     * 解冻e账户金额
     * @param unFreezeEAccountRequest 参数
     */
    @RequestMapping(value = "/unfreezeEAccount", method = RequestMethod.POST)
    public Wrapper<Boolean> unfreezeEAccount(@RequestBody @Valid UnFreezeEAccountRequest unFreezeEAccountRequest) {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long id = unFreezeEAccountRequest.getId();
        String remark = unFreezeEAccountRequest.getRemark();
        BigDecimal amount = unFreezeEAccountRequest.getAmount();
        EAccountStatusRecord eAccountStatusRecord = eAccountStatusService.getEAccountById(id);
        if(eAccountStatusRecord != null){
            Long allInPayId = eAccountStatusRecord.getAllInPayId();
            String tradeCode = eAccountStatusRecord.getAllInPayTraceNo();
            AllInPay allInPay = eAccountService.getAccountDetail(allInPayId);
            if(allInPay != null){
                FreezeMoneyReqVO freezeMoneyReqVO = new FreezeMoneyReqVO();
                freezeMoneyReqVO.setAmount(amount);
                freezeMoneyReqVO.setType(EAccountStatusEnum.Unfreeze.getCode());
                freezeMoneyReqVO.setBizFreeZenNo(tradeCode);
                FreezeMoneyRespVO freezeMoneyRespVO = payService.freezeMoney(allInPay.getMemberId(), allInPay.getMemberRoleId(), freezeMoneyReqVO);
                if(freezeMoneyRespVO != null){
                    EAccountStatusRecord newEAccountStatusRecord = new EAccountStatusRecord();
                    newEAccountStatusRecord.setAllInPayId(allInPay.getId());
                    newEAccountStatusRecord.setStatus(EAccountStatusEnum.Unfreeze.getCode());
                    newEAccountStatusRecord.setOperation(EAccountStatusEnum.Unfreeze.getCode());
                    newEAccountStatusRecord.setAmount(amount);
                    newEAccountStatusRecord.setTraceNo(tradeCode);
                    newEAccountStatusRecord.setAllInPayAmount(freezeMoneyRespVO.getAmount());
                    newEAccountStatusRecord.setAllInPayTraceNo(freezeMoneyRespVO.getBizFreeZenNo());
                    newEAccountStatusRecord.setRemark(remark);
                    newEAccountStatusRecord.setCreateTime(System.currentTimeMillis());
                    newEAccountStatusRecord.setMemberId(sysUser.getMemberId());
                    newEAccountStatusRecord.setMemberName(sysUser.getCompany());
                    newEAccountStatusRecord.setMemberRoleId(sysUser.getMemberRoleId());
                    newEAccountStatusRecord.setMemberRoleName(sysUser.getMemberRoleName());
                    eAccountStatusService.saveEAccountStatusRecord(newEAccountStatusRecord);
                    return Wrapper.success(true);
                }else{
                    return Wrapper.success(false);
                }
            }else{
                throw new BusinessException(ResponseCode.PAY_E_ACCOUNT_NOT_EXIST);
            }
        }else{
            throw new BusinessException(ResponseCode.PAY_E_ACCOUNT_STATUS_RECORD_NOT_EXIST);
        }
    }
}
